﻿
Imports System.Threading
Imports osi.root.connector

Public Class sequentiallock
    'for both 32bit and 64bit system, so use Int32 here, will not fail until there are maxUInt32 threads for a same lock
    Private assignToken As Int32
    Private token As Int32
    Private mre As ManualResetEvent = Nothing
    'Private monitorObj As Object = Nothing

    Public Sub reserve(ByRef tokengot As Int32)
        'can i trust this will all be handled as atom manipulation, include return?
        tokengot = Interlocked.Increment(assignToken)
    End Sub

    Public Sub waitToken(ByVal tokengot As Int32)
        While tokengot > token
            'token increase here by each release call
            mre.WaitOne()
        End While
        mre.Reset()
    End Sub

    Public Sub wait(ByRef tokengot As Int32)
        reserve(tokengot)
        waitToken(tokengot)
        k_assert(tokengot = token, "tokengot < token when wait.")
    End Sub

    Public Sub wait()
        wait(Nothing)
    End Sub

    Public Sub release(ByVal tokengot As Int32)
        k_assert(tokengot = token, "tokengot <> token when release.")
        release()
    End Sub

    Public Sub release()
        Interlocked.Increment(token)
        mre.Set()
        'Monitor.Exit(monitorObj)
    End Sub

    Public Sub New()
        'monitorObj = New Object()
        token = 0
        assignToken = token - 1
        mre = New ManualResetEvent(False)
    End Sub

    Protected Overrides Sub Finalize()
        mre.Close()
        GC.KeepAlive(mre)
        MyBase.Finalize()
    End Sub
End Class
